Skip to content

perf(landing): defer Features preview, memoize integration grid, trim dead weight#5303

Merged
waleedlatif1 merged 5 commits into
stagingfrom
perf/landing
Jul 1, 2026
Merged

perf(landing): defer Features preview, memoize integration grid, trim dead weight#5303
waleedlatif1 merged 5 commits into
stagingfrom
perf/landing

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

Landing performance wins from a verified audit (each finding adversarially confirmed before implementing). No behavior, SEO, or render-mode change — all confirmed empirically.

Defer the Features workflow preview (biggest win)

landing-preview-mount.tsx is code-split (ssr:false) but was mounted eagerly, so its reactflow + framer-motion chunk (~85–100 KB gz) downloaded right after hydration despite sitting below the fold. It's now gated on an IntersectionObserver (400px preload margin, loads once), reusing the existing dimension-stable aspect-[1116/615] placeholder → zero CLS. SEO-neutral (the preview was already ssr:false, so SSR only ever emitted the placeholder).

Memoize the integration grid

integration-grid.tsx rebuilt category facets and re-lowercased ~3,480 operation/trigger strings on every keystroke, and re-rendered all ~220 rows. Now: facets + a per-integration lowercased search index are derived once (useMemo over the stable list), and IntegrationRow is memo'd (both props are stable references). Match semantics are identical (per-field includes, not a joined string — verified: ?q=slack returns the same 6 results).

Hero resize listener

Subscribes once via a phaseRef instead of re-subscribing on every animation phase (~30×/loop).

Delete dead weight

Orphaned public/static/mothership.gif (1.5 MB) + public/landing/sim-mothership.webp (87 KB), the unused static Season font weights (only the loaded variable .woff2 is kept), and the unused CtaChat component — all re-verified unreferenced across the repo.

Not included (deliberately)

  • Hero per-character re-render isolation + off-screen animation gating — real, but the fix touches a 1,191-line animation component (synchronous card-height coupling; restart-from-home gating) and needs a visual-QA pass; deferred to its own change rather than risk an animation regression.
  • Blog next/image unoptimized — left as-is.

Testing

  • tsc --noEmit 0 errors; biome check clean
  • next build: compiled successfully, 712/712 pages, 0 errors; font deletions safe (no next/font errors); render modes unchanged
  • Runtime: /integrations?q=slack returns the identical filtered set (223 → 6); /workflows (a gated-preview consumer) → 200
  • Every change adversarially reviewed (effect/observer lifecycle, filter equivalence, memo prop stability, deletion safety) — no issues

Type of Change

  • Performance / improvement (no behavior change)

The preview is code-split (ssr:false) but was mounted eagerly, so its
reactflow + framer-motion chunk (~85-100 KB gz) downloaded right after hydration
despite sitting below the fold. Gate the dynamic mount on an IntersectionObserver
(400px preload margin, loads once), reusing the existing dimension-stable
aspect-[1116/615] placeholder so there's zero CLS.
Derive the category facets and a per-integration lowercased search index once
from the (stable) integration list instead of rebuilding + re-lowercasing ~3.5k
strings on every keystroke, and memo IntegrationRow so the ~220 rows don't all
re-render per keystroke. Match semantics are identical (per-field includes).
Remove unreferenced public/static/mothership.gif (1.5 MB) and
public/landing/sim-mothership.webp (87 KB), the unused static Season font weights
(only the variable woff2 is loaded), and the unused CtaChat component.
The resize effect re-subscribed on every phase change (~30x/loop); read the
current phase from a ref so the listener is added once for the component's life.
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 1, 2026 12:10am

Request Review

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Performance-only landing changes with preserved filter semantics and CLS-safe preview gating; main risk is edge cases around IntersectionObserver lifecycle or memoized row props, not security or data paths.

Overview
Landing load and interaction performance without intended behavior changes: below-the-fold workflow previews no longer pull the heavy reactflow + framer-motion chunk on first paint, the integrations search UI does less work per keystroke, and the hero resize handler stops re-binding on every animation phase.

Features preview (landing-preview-mount.tsx): the dynamic preview still uses ssr: false and the same aspect-[1116/615] placeholder, but the chunk now loads only after an IntersectionObserver sees the mount (400px preload margin, one-way flip to inView). Without IntersectionObserver, it loads eagerly so the UI does not stay on a blank placeholder.

Integrations grid: category facets and a per-integration lowercased search index are built once via useMemo; filtering uses that index with the same per-field includes semantics as before. IntegrationRow is wrapped in memo to cut unnecessary row re-renders while typing.

Hero visual: window resize uses a phaseRef so the listener is registered once and still snaps the cursor for the current phase.

Cleanup: removes the unused CtaChat component (no remaining references in the repo per this change set).

Reviewed by Cursor Bugbot for commit 3bfabc2. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves landing-page performance without changing the visible page behavior. The main changes are:

  • Defers the heavy landing preview until it nears the viewport.
  • Adds a fallback for browsers without IntersectionObserver.
  • Memoizes integration filtering and row rendering.
  • Keeps the hero resize listener subscribed once.
  • Removes unused landing assets, fonts, and the unused CTA chat component.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/sim/app/(landing)/components/landing-preview/landing-preview-mount.tsx Adds viewport-gated loading for the landing preview and eagerly loads it when IntersectionObserver is unavailable.
apps/sim/app/(landing)/integrations/components/integration-grid.tsx Memoizes category facets, search indexing, and filtered integration results.
apps/sim/app/(landing)/integrations/components/integration-card.tsx Memoizes the integration row component while keeping the same props and named export.
apps/sim/app/(landing)/components/hero/components/hero-visual/hero-visual.tsx Uses a ref so the resize handler reads the current animation phase without resubscribing.

Reviews (2): Last reviewed commit: "perf(landing): load preview eagerly when..." | Re-trigger Greptile

…ailable

Graceful degradation for browsers/WebViews without IntersectionObserver — set
inView immediately instead of leaving the preview stuck on its placeholder
(addresses Greptile P2).
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3bfabc2. Configure here.

@waleedlatif1 waleedlatif1 merged commit 495460d into staging Jul 1, 2026
17 checks passed
@waleedlatif1 waleedlatif1 deleted the perf/landing branch July 1, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant